import spade
from CrawlerAgent import MyPeriodicBehaviour
from sys import argv
import time
from threading import Lock


class StatisticsFile(object):
  '''
  Plik do zapisywania statystyk
  '''
  def __init__(self, path = "statistics.txt"):
    self.path = path
    f         = open(path, "w")
    f.close()
    self.lock = Lock()

  def add(self, string):
    self.lock.acquire()
    f = open(self.path, "a")
    f.write(string)
    f.close()
    self.lock.release()


class StatisticsAgent(spade.Agent.Agent):
  '''
  Agent, ktory zbiera statystyki odnosnie obciazenia agentow crawlujacych
  '''
  class QueryLoadBehaviour(MyPeriodicBehaviour):
    def __init__(self, period, timestart):
      #mam nadzieje, ze dzieki temu statystyk bedzie sie komunikowal tylko z crawlerami
      self.service_name = 'url_transfer'
      self.template     = spade.DF.DfAgentDescription()
      sd                = spade.DF.ServiceDescription()
      sd.setType(self.service_name)
      self.template.addService(sd)
      MyPeriodicBehaviour.__init__(self, period, timestart)

    def _onTick(self):
      try:
        res = self.myAgent.searchService(self.template)
        #FIXME: tu wystepuje blad?
        res = map(lambda a: a.getName(), res)
        print res
        tm = str(time.time())
        for aname in res:
          #zapytanie o obciazenie
          receiver = spade.AID.aid(name=aname, addresses=['xmpp://' + aname])
          msg      = spade.ACLMessage.ACLMessage()
          msg.setPerformative('query-ref')
          msg.setOntology('statistics')
          msg.addReceiver(receiver)
          msg.setContent( tm )
          self.myAgent.send(msg)
      except Exception, e:
        print "QueryLoadError", e
        print "Res:", res, type(res), self.template

  class ReceiveLoadBehaviour(spade.Behaviour.Behaviour):
    def _process(self):
      msg = None
      msg = self._receive()
      if msg:
        try:
##          print "ReceiveLoad"
          load   = msg.getContent()
          sender = msg.getSender()
          sender = sender.getName()
          print sender, load
          t,_, rest    = load.partition("#")
          qsize, _, tm = rest.partition("#")
          self.myAgent.stat_f.add( "%s\t%s\t%s\t%s\n" % (tm,sender, t, qsize) )
          #TODO: wypisywanie na terminal
        except Exception, e:
          print "ReceiveError", e

  def add_service(self, stype):
    sd = spade.DF.ServiceDescription()
    sd.setName(stype + ' service')
    sd.setType(stype)
    dfd = spade.DF.DfAgentDescription()
    dfd.getServices()
    dfd.addService(sd)
    dfd.setAID(self.getAID())
    self.registerService(dfd)
    print 'registered'

  def _setup(self):
    print self.getName()

    self.stat_f = StatisticsFile()

    template = spade.Behaviour.ACLTemplate()
    template.setPerformative('inform')
    template.setOntology('statistics')
    mt = spade.Behaviour.MessageTemplate(template)
    rb = self.ReceiveLoadBehaviour()
    self.addBehaviour(rb, mt)

    mb = self.QueryLoadBehaviour(10, 7)
    self.addBehaviour(mb)
    self.add_service('statistics')

if __name__ == '__main__':
  s = StatisticsAgent(argv[1] + '@' + argv[2], 'secret')
  s.start()
